using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using OccurrencesCore.Model;
using OccurrencesCore.Model.Interface;
using OccurrencesCore.Repository;

namespace OccurrencesCore.Service
{
    public abstract class BaseService<TEntity, TRepository>
        where TEntity : class
        where TRepository : IBaseRepository<TEntity>
    {
        protected TRepository _Repository;

        protected BaseService(IBaseRepository<TEntity> repository)
        {
            _Repository = (TRepository)repository;
        }

        public List<TEntity> FindAll()
        {
            return _Repository.FindAll().ToList();
        }

        public TEntity FindByKey(int entityId)
        {
            return _Repository.FindById(entityId);
        }

        public TEntity Create(TEntity entity)
        {
			SetIModifiableProperties(entity, true);
            return _Repository.Create(entity);
        }

		public IList<TEntity> Create(IList<TEntity> entities)
        {
			foreach(TEntity entity in entities)
			{
				SetIModifiableProperties(entity, true);
			}
            return _Repository.Create(entities);
        }

        public TEntity Update(TEntity entity)
        {		 
            SetIModifiableProperties(entity, false);
            return _Repository.Update(entity);
        }

		public IList<TEntity> Update(IList<TEntity> entities)
        {
			foreach(TEntity entity in entities)
			{
				SetIModifiableProperties(entity, false);
			}
            return _Repository.Update(entities);
        }		

        public void Delete(int entityId)
        {
            _Repository.Remove(entityId);
        }

		public void Delete(TEntity entity)
        {
            _Repository.Remove(entity);
        }

		public void Delete(IList<TEntity> entities)
        {
            _Repository.Remove(entities);
        }

		public IList<TEntity> PagedList(int pageNumber, int pageSize)
		{
			return _Repository.PagedList(pageNumber, pageSize);
		}

		private void SetIModifiableProperties(TEntity entity, bool setCreate)
		{
			IModifiableItem modifiable = entity as IModifiableItem;
		    if (modifiable != null)
            {
                User currentUser = new UserService().GetCurrentUser();
                DateTime actualTime = DateTime.Now;
				if (setCreate)
				{
					modifiable.CreatedBy = currentUser;                
					modifiable.CreatedAt = actualTime;
				}
				modifiable.ModifiedBy = currentUser;
                modifiable.ModifiedAt = actualTime;
            }   
		}
    }
}
